// WITH_STDLIB
import kotlin.test.*

// Prevent constant folding, test the actual runtime implementation
infix fun Int.myshr(bitCount: Int) = shr(bitCount)
infix fun Int.myshl(bitCount: Int) = shl(bitCount)
infix fun Int.myushr(bitCount: Int) = ushr(bitCount)
infix fun Long.myshr(bitCount: Int) = shr(bitCount)
infix fun Long.myshl(bitCount: Int) = shl(bitCount)
infix fun Long.myushr(bitCount: Int) = ushr(bitCount)

fun box(): String {
    // Int
    assertEquals(Int.MIN_VALUE, 1 myshl -1, "1 shl -1")
    assertEquals(0, 0 myshr -1, "0 shr -1")
    assertEquals(0, 1 myshr -1, "1 shr -1")
    assertEquals(0, 2 myshr -1, "2 shr -1")
    assertEquals(-1, Int.MIN_VALUE myshr -1, "Int.MIN_VALUE shr -1")
    assertEquals(0, Int.MAX_VALUE myshr -1, "Int.MAX_VALUE shr -1")
    assertEquals(0, 0x8000000 myshr -1, "0x80000000 shr -1")
    assertEquals(2048, 0x8000000 myshr -16, "0x80000000 shr -16")
    assertEquals(0, 0 myshl -1, "0 shl -1")
    assertEquals(Int.MIN_VALUE, 1 myshl -1, "1 shl -1")
    assertEquals(0, 2 myshl -1, "2 shl -1")
    assertEquals(0, Int.MIN_VALUE myshl -1, "Int.MIN_VALUE shl -1")
    assertEquals(Int.MIN_VALUE, Int.MAX_VALUE myshl -1, "Int.MAX_VALUE shl -1")
    assertEquals(0, 0x8000000 myshl -1, "0x80000000 shl -1")
    assertEquals(0, 0x8000000 myshl -16, "0x80000000 shl -16")
    assertEquals(0, 0 myushr -1, "0 ushr -1")
    assertEquals(0, 1 myushr -1, "1 ushr -1")
    assertEquals(0, 2 myushr -1, "2 ushr -1")
    assertEquals(1, Int.MIN_VALUE myushr -1, "Int.MIN_VALUE ushr -1")
    assertEquals(0, Int.MAX_VALUE myushr -1, "Int.MAX_VALUE ushr -1")
    assertEquals(0, 0x8000000 myushr -1, "0x80000000 ushr -1")
    assertEquals(2048, 0x8000000 myushr -16, "0x80000000 ushr -16")
    assertEquals(1, 1 myshl 32, "1 shl 32")
    assertEquals(1073741823, -1 myushr 2, "-1 ushr 2")
    assertEquals(-1, -1 myshr 2, "-1 shr 2")

    // Long
    assertEquals(Long.MIN_VALUE, 1L myshl -1, "1L shl -1")
    assertEquals(0L, 0L myshr -1, "0L shr -1")
    assertEquals(0L, 1L myshr -1, "1L shr -1")
    assertEquals(0L, 2L myshr -1, "2L shr -1")
    assertEquals(-1L, Long.MIN_VALUE myshr -1, "Long.MIN_VALUE shr -1")
    assertEquals(0L, Long.MAX_VALUE myshr -1, "Long.MAX_VALUE shr -1")
    assertEquals(0L, 0x800000000000000 myshr -1, "0x8000000000000000 shr -1")
    assertEquals(134217728L, 0x800000000000000 myshr -32, "0x8000000000000000 shr -32")
    assertEquals(0L, 0L myshl -1, "0L shl -1")
    assertEquals(Long.MIN_VALUE, 1L myshl -1, "1L shl -1")
    assertEquals(0L, 2L myshl -1, "2L shl -1")
    assertEquals(0L, Long.MIN_VALUE myshl -1, "Long.MIN_VALUE shl -1")
    assertEquals(Long.MIN_VALUE, Long.MAX_VALUE myshl -1, "Long.MAX_VALUE shl -1")
    assertEquals(0L, 0x800000000000000 myshl -1, "0x8000000000000000 shl -1")
    assertEquals(0L, 0x800000000000000 myshl -32, "0x8000000000000000 shl -32")
    assertEquals(0L, 0L myushr -1, "0L ushr -1")
    assertEquals(0L, 1L myushr -1, "1L ushr -1")
    assertEquals(0L, 2L myushr -1, "2L ushr -1")
    assertEquals(1L, Long.MIN_VALUE myushr -1, "Long.MIN_VALUE ushr -1")
    assertEquals(0L, Long.MAX_VALUE myushr -1, "Long.MAX_VALUE ushr -1")
    assertEquals(0L, 0x800000000000000 myushr -1, "0x8000000000000000 ushr -1")
    assertEquals(134217728L, 0x800000000000000 myushr -32, "0x8000000000000000 ushr -32")
    assertEquals(1L, 1L myshl 64, "1L shl 64")
    assertEquals(4611686018427387903L, -1L myushr 2, "-1L ushr 2")
    assertEquals(-1L, -1L myshr 2, "-1L shr 2")

    return "OK"
}
